package com.waverider.promotion.web.bg.action;

import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;

import com.iacrqq.util.StringUtil;
import com.taobao.api.domain.Item;
import com.waverider.promotion.biz.manager.ItemManager;
import com.waverider.promotion.domain.PromotionDO;
import com.waverider.promotion.enums.PromotionStatusEnum;
import com.waverider.promotion.enums.PromotionTypeEnum;
import com.waverider.promotion.exception.ValidateException;
import com.waverider.promotion.web.AbstractLoginedController;

/**
 * 
 * @author sihai
 * 
 */
public class PromotionAction extends AbstractLoginedController {
	private static final Log logger = LogFactory.getLog(PromotionAction.class);

	private static final String DISCOUNT_OPERATION_ADD = "_add_";
	private static final String DISCOUNT_OPERATION_UPDATE = "_update_";
	private static final String DISCOUNT_OPERATION_DELETE = "_delete_";

	private ItemManager itemManager;

	@Override
	protected ModelAndView handleLogined(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String operation = request.getParameter(OPERATION_KEY);
		if (StringUtil.equals(DISCOUNT_OPERATION_ADD, operation)) {
			return doAdd(request, response);
		} else if (StringUtil.equals(DISCOUNT_OPERATION_UPDATE, operation)) {
			return doUpdate(request, response);
		} else if (StringUtil.equals(DISCOUNT_OPERATION_DELETE, operation)) {
			return doDelete(request, response);
		}

		ModelAndView mv = new ModelAndView("bg/error");
		mv.getModel().put(ERROR_MSG, UNKNOWN_OPERATION_ERROR_MSG);

		return mv;
	}

	private ModelAndView doAdd(HttpServletRequest request,
			HttpServletResponse response) {
		Map<String, Object> map = new HashMap<String, Object>();

		try {
			PromotionDO promotion = new PromotionDO();
			HttpSession session = request.getSession();
			Long goodsId = Long.valueOf(request.getParameter("goods_id"));
			promotion.setGoodsId(goodsId);
			promotion.setShopId(getShopId(session));

			Item item = itemManager.getItem(this.getSessionKey(session),
					goodsId);
			promotion.setOriginalPrice(new BigDecimal(item.getPrice()));
			promotion.setCurrentPrice(promotion.getOriginalPrice());
			promotion.setGoodsName(item.getTitle());
			promotion.setGoodsDetailURL(item.getDetailUrl());
			promotion.setGoodsPicURL(item.getPicUrl());

			setPromotion(promotion, request);

			itemManager.addPromotion(getSessionKey(session), item, promotion);

			try {
				map.put(JSON_SUCCEED_KEY, true);
				map.put(JSON_ERROR_MSG_KEY, "");

				Writer writer = response.getWriter();
				writer.write(JSONObject.fromObject(map).toString());
				writer.flush();
			} catch (IOException e) {
				logger.error(e);
			}

			return null;
			// return new ModelAndView("bg/itemList");
		} catch (ValidateException e) {
			try {
				map.put(JSON_SUCCEED_KEY, false);
				map.put(JSON_ERROR_MSG_KEY, e.getMessage());
				Writer writer = response.getWriter();
				writer.write(JSONObject.fromObject(map).toString());
				writer.flush();
			} catch (IOException ex) {
				logger.error(ex);
			}
			return null;
		}
	}

	private ModelAndView doUpdate(HttpServletRequest request,
			HttpServletResponse response) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			HttpSession session = request.getSession();
			Long promotionId = Long.valueOf(request
					.getParameter("promotion_id"));
			PromotionDO promotion = itemManager.getPromotionById(promotionId);
			int status = promotion.getStatus();
			if (status == PromotionStatusEnum.PROMOTION_STATUS_END.value()) {
				throw new ValidateException("该优惠已经结束，禁止修改，请等结束后修改！！！");
			}
			setPromotion(promotion, request);

			// FIXME
			itemManager.updatePromotion(getSessionKey(session), promotion,
					false);

			try {
				map.put(JSON_SUCCEED_KEY, true);
				map.put(JSON_ERROR_MSG_KEY, "");

				Writer writer = response.getWriter();
				writer.write(JSONObject.fromObject(map).toString());
				writer.flush();
			} catch (IOException e) {
				logger.error(e);
			}

			return null;
		} catch (ValidateException e) {
			try {
				map.put(JSON_SUCCEED_KEY, false);
				map.put(JSON_ERROR_MSG_KEY, e.getMessage());
				Writer writer = response.getWriter();
				writer.write(JSONObject.fromObject(map).toString());
				writer.flush();
			} catch (IOException ex) {
				logger.error(ex);
			}
			return null;
		}
	}

	private ModelAndView doDelete(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		Long promotionId = Long.valueOf(request.getParameter("promotion_id"));
		Long goodsId = Long.valueOf(request.getParameter("goods_id"));
		itemManager.delete(getSessionKey(session), promotionId, goodsId);

		// 先这样
		return new ModelAndView("redirect:/bg/itemList.htm");
	}

	private void setPromotion(PromotionDO promotion, HttpServletRequest request)
			throws ValidateException {
		String title = request.getParameter("title");
		if (StringUtil.isBlank(title)) {
			throw new ValidateException("请填写活动标题！！！");
		}

		promotion.setTitle(title);
		Integer type = Integer.valueOf(request.getParameter("type"));
		promotion.setType(type);
		PromotionTypeEnum promotionType = PromotionTypeEnum.toEnum(type);
		if (promotionType == PromotionTypeEnum.PROMOTION_TYPE_DISCOUNT) {
			Integer lowestDiscount = null;
			String strLowestDiscount = request.getParameter("lowest_discount");
			if (StringUtil.isBlank(strLowestDiscount)) {
				throw new ValidateException("请填写最低折扣！！！");
			}

			try {
				lowestDiscount = Integer.valueOf(strLowestDiscount);
				promotion.setLowestDiscount(lowestDiscount);
			} catch (NumberFormatException e) {
				throw new ValidateException("请填写正确格式的最低折扣(数字)！！！");
			}

			String strOrderCount = request.getParameter("discount_order_count");
			if (StringUtil.isBlank(strOrderCount)) {
				throw new ValidateException("请填写使折扣降到最低的购买数量！！！");
			}

			try {
				Long orderCount = Long.valueOf(strOrderCount);
				promotion.setDiscountIncreaseUnit((100 - lowestDiscount)
						/ (orderCount + 0.0D));
				promotion.setOrderCount(orderCount);
			} catch (NumberFormatException e) {
				throw new ValidateException("请填写正确格式的使折扣降到最低的购买数量(数字)！！！");
			}

			promotion.setCurrentDiscount(100);
		} else if (promotionType == PromotionTypeEnum.PROMOTION_TYPE_REDUE_PRICE) {
			BigDecimal lowestPrice = null;
			String strLowestPrice = request.getParameter("lowest_price");
			if (StringUtil.isBlank(strLowestPrice)) {
				throw new ValidateException("请填写最低价格！！！");
			}

			try {
				lowestPrice = new BigDecimal(strLowestPrice);
				promotion.setLowestPrice(lowestPrice);
			} catch (NumberFormatException e) {
				throw new ValidateException("请填写正确格式的最低价格(数字)！！！");
			}

			String strOrderCount = request.getParameter("price_order_count");
			if (StringUtil.isBlank(strOrderCount)) {
				throw new ValidateException("请填写使价格降到最低价格的购买数量！！！");
			}

			try {
				Long orderCount = Long.valueOf(strOrderCount);
				promotion.setPriceReduceUnit(promotion.getOriginalPrice()
						.subtract(lowestPrice)
						.divide(new BigDecimal(orderCount)));
				promotion.setOrderCount(orderCount);
			} catch (NumberFormatException e) {
				throw new ValidateException("请填写正确格式的使折扣降到最低的购买数量(数字)！！！");
			}

			promotion.setCurrentPrice(promotion.getOriginalPrice());
		}

		String strInitOrderCount = request.getParameter("init_order_count");
		String strFullPromotionQuota = request
				.getParameter("full_promotion_quota");

		if (!StringUtil.isBlank(strInitOrderCount)) {
			promotion.setInitOrderCount(Long.valueOf(strInitOrderCount));
		} else {
			promotion.setInitOrderCount(0L);
		}

		if (!StringUtil.isBlank(strFullPromotionQuota)) {
			promotion.setFullPromotionQuota(Integer
					.valueOf(strFullPromotionQuota));
		} else {
			promotion.setFullPromotionQuota(0);
		}

		promotion.setCurrentOrderCount(0L);

		boolean startNow = StringUtil.equals(request.getParameter("start_now"),
				"1");
		String strStartTime = request.getParameter("start_time");
		String strEndTime = request.getParameter("end_time");

		if (!startNow && StringUtil.isBlank(strStartTime)) {
			throw new ValidateException("请填写优惠开始时间！！！");
		}

		if (StringUtil.isBlank(strEndTime)) {
			throw new ValidateException("请填写优惠结束时间！！！");
		}

		SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
		format.setTimeZone(TimeZone.getDefault());

		Date startTime = null;
		Date endTime = null;

		if (!startNow) {
			try {
				startTime = format.parse(strStartTime);
			} catch (ParseException e) {
				throw new ValidateException("请填写正确格式的优惠开始时间！！！");
			}
		} else {
			startTime = new Date();
		}

		try {
			endTime = format.parse(strEndTime);
		} catch (ParseException e) {
			throw new ValidateException("请填写正确格式的优惠结束时间！！！");
		}

		if (endTime.before(startTime)) {
			throw new ValidateException("结束日期必须大于等于开始日期！！！");
		}

		if (endTime.getTime() - startTime.getTime() > 1 * 60 * 60 * 1000)
			throw new ValidateException(
					"[[免费版]]：活动设定时间不能超过一个小时，请到淘宝服务平台订购收费版本！！！");

		if (itemManager.getValidatePromotionCountByShopId(getShopId(request
				.getSession())) >= 3)
			throw new ValidateException("[[免费版]]：创建的优惠数量不能超过3个，请到淘宝服务平台订购收费版本！！！");

		Date now = new Date();
		if (!startNow && startTime.before(now)) {
			throw new ValidateException("开始日期必须大于等于当前日期！！！");
		}

		promotion.setStartTime(startTime);
		promotion.setEndTime(endTime);

		if (startNow) {
			promotion.setStatus(PromotionStatusEnum.PROMOTION_STATUS_STARTED
					.value());
		} else if (startTime.after(now)) {
			promotion.setStatus(PromotionStatusEnum.PROMOTION_STATUS_NOT_START
					.value());
		} else {
			promotion.setStatus(PromotionStatusEnum.PROMOTION_STATUS_STARTED
					.value());
		}

		promotion.setIsDeleted(false);
	}

	public void setItemManager(ItemManager itemManager) {
		this.itemManager = itemManager;
	}
}
